home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 18 / CU Amiga Magazine's Super CD-ROM 18 (1997)(EMAP Images)(GB)[!][issue 1998-01].iso / CUCD / Programming / AmigaE / Src / Utils / EDBG / edbg.e next >
Encoding:
Text File  |  1997-10-26  |  38.5 KB  |  1,425 lines

  1. -> Yes! A real E debugger!
  2.  
  3. OPT OSVERSION=37, LARGE
  4.  
  5. MODULE 'tools/clonescreen', 'tools/macros', 'tools/arexx',
  6.        'tools/EasyGUI', 'tools/constructors', 'tools/exceptions',
  7.        'tools/iterators',
  8.        '*eexe', 'class/sc', '*sctext', '*schex', '*screg', 'other/sendexplorer',
  9.        'dos/dostags', 'exec/lists', 'exec/nodes',
  10.        'gadtools', 'libraries/gadtools',
  11.        'intuition/intuition', 'intuition/screens', 'intuition/gadgetclass',
  12.        'graphics/text', 'graphics/rastport',
  13.        'rexx/storage', 'rexxsyslib'
  14.  
  15. OBJECT dbgwin
  16.   next:PTR TO dbgwin,type
  17. ENDOBJECT
  18.  
  19. OBJECT srcwin OF dbgwin
  20.   scwin:PTR TO scrolltext,src:PTR TO e_source
  21. ENDOBJECT
  22.  
  23. OBJECT memwin OF dbgwin
  24.   scwin:PTR TO scrollhex,addr
  25. ENDOBJECT
  26.  
  27. OBJECT regwin OF dbgwin
  28.   scwin:PTR TO scrollreg
  29. ENDOBJECT
  30.  
  31. OBJECT varwin OF dbgwin
  32.   scwin:PTR TO scrolltext
  33. ENDOBJECT
  34.  
  35. OBJECT wvar OF ln
  36.   v:PTR TO CHAR
  37. ENDOBJECT
  38.  
  39. CONST RXSTR_SIZE=250
  40.  
  41. DEF exe=NIL:PTR TO e_exe,frame:PTR TO stackframe,
  42.     oscr=NIL,scr=NIL:PTR TO screen,font=NIL:PTR TO textfont,depth,xsize,ysize,
  43.     title,doabout=TRUE,dorefresh=TRUE,dosavewindowpos=TRUE,dosavevars=TRUE,argstring[100]:STRING,
  44.     dwins=NIL:PTR TO dbgwin,numsrc=0,wrapsrc=FALSE,maxsrcs=0,stackwin=NIL:PTR TO memwin,
  45.     vwin=NIL:PTR TO varwin,varlist=NIL:PTR TO LONG,vars:PTR TO lh,
  46.     rwin=NIL:PTR TO regwin,
  47.     visual=NIL,menu=NIL,whatstep,evgh=NIL:PTR TO guihandle,
  48.     followgh=NIL:PTR TO guihandle,followspeed=30,repeatcount=0,repeatover=TRUE,
  49.     toolwin=NIL:PTR TO window,toolgads=NIL:PTR TO LONG,
  50.     currentwin:PTR TO srcwin,        -> active intuition
  51.     activewin:PTR TO srcwin,        -> where (pc) is
  52.     lastsec=0,lastmic=0,findstr[100]:STRING,offstr[12]:STRING,
  53.     ocon=NIL,reqtitle,oldi,oldo,
  54.     first_step_done=FALSE,unreachablea7,
  55.     srcport=NIL,rexxport=NIL,rexxname,startExp=FALSE,oldvy=-1,
  56.     fx=0,fy=0,fxs=0,fys=0,explorer[RXSTR_SIZE]:STRING,pubname[100]:STRING,
  57.     rxs1[RXSTR_SIZE]:STRING,rxs2[RXSTR_SIZE]:STRING,rxs3[RXSTR_SIZE]:STRING
  58.  
  59. ENUM STEP_NONE,STEP_IN,STEP_OVER,STEP_RUN,STEP_THROW,STEP_FOLLOW
  60.  
  61. CONST MAX_WATCH=250, MAX_WLINE=100
  62.  
  63. RAISE "MEM" IF String()=NIL
  64.  
  65. PROC main() HANDLE
  66.   DEF options:PTR TO LONG,rdargs=NIL,exename[100]:STRING,e:PTR TO dbgwin,
  67.       pubconname[200]:STRING, i
  68.   title:='EDBG v3.3a, The E Debugger! © 1994-1997 Wouter (and Jason)'
  69.   reqtitle:='EDBG'
  70.   vars:=newlist()
  71.   options:=[0,0,0]
  72.   IF rdargs:=ReadArgs('EXECUTABLE/A,PUBSCREEN/K,ARG/K',options,NIL)
  73.     StrCopy(exename,options[0])
  74.     IF options[2] THEN StrCopy(argstring,options[2])
  75.     IF options[1]
  76.       StrCopy(pubname,options[1])
  77.       IF scr:=LockPubScreen(pubname) THEN font:=scr.rastport::rastport.font
  78.     ENDIF
  79.     FreeArgs(rdargs)
  80.   ELSE
  81.     Raise("ARGS")
  82.   ENDIF
  83.   WriteF('\s.\nLoading "\s"...\n',title,exename)
  84.   NEW exe.load(exename)
  85.   IF scr=NIL
  86.     StrCopy(pubname,'EDBG')
  87.     IF options[1] THEN StrAdd(pubname,options[1])
  88.     scr,font:=openclonescreen('Workbench',title,2,pubname)
  89.     oscr:=scr
  90.     PubScreenStatus(scr,0)       -> TEMP!!
  91.   ENDIF
  92.   rexxname:=IF oscr THEN pubname ELSE 'EDBG'
  93.   depth,xsize,ysize:=getcloneinfo(scr)
  94.   IF (gadtoolsbase:=OpenLibrary('gadtools.library',37))=NIL THEN Raise("GT")
  95.   IF (visual:=GetVisualInfoA(scr,NIL))=NIL THEN Raise("MENU")
  96.   createmenus()
  97.   createtoolbar()
  98.   IF (srcport:=CreateMsgPort())=NIL THEN Raise("PORT")
  99.   rexxport:=rx_OpenPort(rexxname)
  100.   StrCopy(pubconname,'CON:0/900/640/50/Standard Input and Output:/SCREEN ')
  101.   StrAdd(pubconname,pubname)
  102.   IF ocon:=Open(pubconname,NEWFILE)
  103.     oldi:=SelectInput(ocon)
  104.     oldo:=SelectOutput(ocon)
  105.   ELSE
  106.     Throw("OPEN",'CON:')
  107.   ENDIF
  108.   exe.edebug({step},argstring)
  109. EXCEPT DO
  110.   IF followgh OR repeatcount THEN Delay(6) BUT request1('Program completed execution','_OK',"o")
  111.   IF startExp
  112.     quitExplorer()
  113.     FOR i:=1 TO 20
  114.     EXIT isExplorerRunning()=FALSE
  115.       Delay(6)
  116.     ENDFOR
  117.   ENDIF
  118.   removefollow()
  119.   WHILE dwins
  120.     e:=dwins
  121.     dwins:=dwins.next
  122.     END e
  123.   ENDWHILE
  124.   IF ocon
  125.     SelectInput(oldi)
  126.     SelectOutput(oldo)
  127.     Close(ocon)
  128.   ENDIF
  129.   rx_ClosePort(rexxport)
  130.   rexxport:=NIL
  131.   IF srcport THEN DeleteMsgPort(srcport)
  132.   deletetoolbar()      -> no request()s after this
  133.   IF menu THEN FreeMenus(menu)
  134.   IF visual THEN FreeVisualInfo(visual)
  135.   IF gadtoolsbase THEN CloseLibrary(gadtoolsbase)
  136.   IF oscr
  137.     IF closeclonescreen(oscr,font)=FALSE
  138.       Delay(20)
  139.       WHILE closeclonescreen(oscr,font)=FALSE
  140.         request1('Please close other windows on this screen!','_OK',"o")
  141.       ENDWHILE
  142.     ENDIF
  143.   ELSEIF scr
  144.     UnlockPubScreen(NIL,scr)
  145.   ENDIF
  146.   END exe
  147.   SELECT exception
  148.     CASE "MEM";  WriteF('Aaargh! no mem!\n')
  149.     CASE "ARGS"; WriteF('Bad Args! (try "edbg ?")\n')
  150.     CASE "OPEN"; WriteF('Failed to open "\s".\n',exceptioninfo)
  151.     CASE "IN";   WriteF('Problems while reading file.\n')
  152.     CASE "eexe"; WriteF('Not a valid E executable\n')
  153.     CASE "eexd"; WriteF('Try compiling with "EC DEBUG" first\n')
  154.     CASE "SCR";  WriteF('no screen!\n')
  155.     CASE "GT";   WriteF('no "gadtools.library"!\n')
  156.     CASE "MENU"; WriteF('no menus!\n')
  157.     CASE "WIN";  WriteF('no window!\n')
  158.     CASE "DOUB"; WriteF('port with same name already exists! (another EDBG running?)\n')
  159.     CASE "SIG";  WriteF('could not allocate signal!\n')
  160.     DEFAULT; report_exception()
  161.   ENDSELECT
  162. ENDPROC
  163.  
  164. PROC createmenus()
  165.   IF (menu:=CreateMenusA([
  166.     1,0,'Project',0,0,0,0,
  167.       2,0,'About...',            0 ,0,0,0,
  168.       2,0,'Settings...',        'P',0,0,0,
  169.       2,0,'Save Settings',      'W',0,0,0,
  170.       2,0,'Quit',               'Q',0,0,0,
  171.     1,0,'Windows',0,0,0,0,
  172.       2,0,'Source',             'S',0,0,0,
  173.       2,0,'Registers',          'D',0,0,0,
  174.       2,0,'Memory',             'M',0,0,0,
  175.       2,0,'Stack',              'T',0,0,0,
  176.       2,0,'Variables',          'X',0,0,0,
  177.     1,0,'Debug',0,0,0,0,
  178.       2,0,'Step In (left)',     'I',0,0,0,
  179.       2,0,'Step Over (down)',   'O',0,0,0,
  180.       2,0,'Step Follow',         0 ,0,0,0,
  181.       2,0,'Repeat Step',         0 ,0,0,0,
  182.       2,0,'Watch Variable',      0 ,0,0,0,
  183.       2,0,'Set Breakpoint',      0 ,0,0,0,
  184.       2,0,'Memory Breakpoint',  'B',0,0,0,
  185.       2,0,'Clear Breakpoints',  'C',0,0,0,
  186.       2,0,'Run upto Breakpoint','R',0,0,0,
  187.       2,0,'Raise Exception',    'E',0,0,0,
  188.     1,0,'Tools',0,0,0,0,
  189.       2,0,'Eval E Expression',  'K',0,0,0,
  190.       2,0,'Modify Variable',     0 ,0,0,0,
  191.       2,0,'Refresh Views',      'V',0,0,0,
  192.       2,0,'Find in Source',     'F',0,0,0,
  193.       2,0,'Locate Offset',      'L',0,0,0,
  194.     1,0,'Rexx',0,0,0,0,
  195.       2,0,'Execute script 1',    0 ,0,0,0,
  196.       2,0,'Execute script 2',    0 ,0,0,0,
  197.       2,0,'Execute script 3',    0 ,0,0,0,
  198.     0,0,0,0,0,0,0]:newmenu,NIL))=NIL THEN Raise("MENU")
  199.   IF LayoutMenusA(menu,visual,[GTMN_NEWLOOKMENUS,TRUE,NIL])=FALSE THEN Raise("MENU")
  200. ENDPROC
  201.  
  202. /*-----------------------------------------------------------------------*/
  203.  
  204. ENUM T_SRC,T_MEM,T_STACK,T_REG,T_VAR
  205.  
  206. PROC message() OF dbgwin
  207.   IF self.next THEN self.next.message()
  208. ENDPROC
  209.  
  210. PROC refresh() OF dbgwin
  211.   IF self.next THEN self.next.refresh()
  212. ENDPROC
  213.  
  214. PROC end() OF dbgwin
  215.   DEF x:PTR TO dbgwin
  216.   IF (x:=dwins)=self
  217.     dwins:=self.next
  218.   ELSE
  219.     WHILE x.next
  220.     EXIT x.next=self
  221.       x:=x.next
  222.     ENDWHILE
  223.     IF x.next THEN x.next:=self.next
  224.   ENDIF
  225. ENDPROC
  226.  
  227. /*----------------------------------------------------------------------*/
  228.  
  229. PROC srcwin(src:PTR TO e_source) OF srcwin
  230.   DEF x:PTR TO scrolltext,a
  231.   self.next:=dwins
  232.   dwins:=self
  233.   self.type:=T_SRC
  234.   self.src:=src
  235.   self.scwin:=NEW x.settext(src.lines(),120)
  236.   IF (fx>=xsize) OR (fy>=ysize) OR (fxs>=xsize) OR (fys>=ysize) OR (fxs<40) OR (fys<20)
  237.     a:=(numsrc+1)*(font.ysize+3)+IF wrapsrc THEN 5 ELSE 0
  238.     IF maxsrcs=0
  239.       IF ysize-a<(10*font.ysize)
  240.         maxsrcs:=numsrc
  241.         numsrc:=0
  242.         wrapsrc:=TRUE
  243.         a:=font.ysize+3+5
  244.       ENDIF
  245.     ENDIF
  246.     fx:=numsrc*10+49+IF wrapsrc THEN 5 ELSE 0
  247.     fy:=a
  248.     fxs:=500
  249.     fys:=Min(ysize-a,400)
  250.   ENDIF
  251.   x.open(src.name(),fx,fy,fxs,fys,scr,IDCMP_MENUPICK OR IDCMP_MOUSEBUTTONS OR IDCMP_RAWKEY,{handlesrc},srcport,self)
  252.   IF SetMenuStrip(x.window,menu)=FALSE THEN Raise("MENU")
  253.   IF (numsrc++>=maxsrcs) AND maxsrcs
  254.     numsrc:=0
  255.     wrapsrc:=(wrapsrc=FALSE)
  256.   ENDIF
  257.   fx:=fy:=fxs:=fys:=0
  258. ENDPROC
  259.  
  260. PROC end() OF srcwin
  261.   DEF sc:PTR TO scrolltext
  262.   sc:=self.scwin
  263.   IF sc.window THEN ClearMenuStrip(sc.window)
  264.   END sc
  265.   SUPER self.end()
  266.   IF 0>numsrc-- THEN numsrc:=maxsrcs
  267. ENDPROC
  268.  
  269. /*----------------------------------------------------------------------*/
  270.  
  271. PROC memwin(addr,type) OF memwin
  272.   DEF x:PTR TO scrollhex,a
  273.   self.next:=dwins
  274.   dwins:=self
  275.   self.type:=type
  276.   self.addr:=addr
  277.   IF type=T_STACK THEN stackwin:=self
  278.   self.scwin:=NEW x.setmem(addr)
  279.   a:=40*font.xsize+20
  280.   x.open(IF type=T_MEM THEN 'Memory View' ELSE 'Stack View',
  281.          xsize-a,font.ysize+3,a,ysize/3,scr,IDCMP_MENUPICK,{handlesrc})
  282.   IF SetMenuStrip(x.window,menu)=FALSE THEN Raise("MENU")
  283. ENDPROC
  284.  
  285. PROC message() OF memwin
  286.   self.scwin.setmem(self.addr)
  287.   IF self.next THEN self.next.message()
  288.   IF self.scwin.handle() THEN END self
  289. ENDPROC
  290.  
  291. PROC refresh() OF memwin
  292.   self.scwin.setmem(self.addr)
  293.   self.scwin.refreshwindow()
  294.   IF self.next THEN self.next.refresh()
  295. ENDPROC
  296.  
  297. PROC end() OF memwin
  298.   DEF sc:PTR TO scrolltext
  299.   sc:=self.scwin
  300.   IF self.type=T_STACK THEN stackwin:=NIL
  301.   IF sc.window THEN ClearMenuStrip(sc.window)
  302.   END sc
  303.   SUPER self.end()
  304. ENDPROC
  305.  
  306. /*----------------------------------------------------------------------*/
  307.  
  308. PROC regwin() OF regwin
  309.   DEF x:PTR TO scrollreg,a
  310.   self.next:=dwins
  311.   dwins:=self
  312.   self.type:=T_REG
  313.   self.scwin:=NEW x.scrollreg(frame)
  314.   a:=13*font.xsize+20
  315.   x.open('Register View',xsize-a,font.ysize+3,a,ysize/2,scr,IDCMP_MENUPICK,{handlesrc})
  316.   IF SetMenuStrip(x.window,menu)=FALSE THEN Raise("MENU")
  317.   rwin:=self
  318. ENDPROC
  319.  
  320. PROC message() OF regwin
  321.   IF self.next THEN self.next.message()
  322.   IF self.scwin.handle() THEN END self
  323. ENDPROC
  324.  
  325. PROC refresh() OF regwin
  326.   self.scwin.refreshreg(frame)
  327.   IF self.next THEN self.next.refresh()
  328. ENDPROC
  329.  
  330. PROC end() OF regwin
  331.   DEF sc:PTR TO scrolltext
  332.   rwin:=NIL
  333.   sc:=self.scwin
  334.   IF sc.window THEN ClearMenuStrip(sc.window)
  335.   END sc
  336.   SUPER self.end()
  337. ENDPROC
  338.  
  339. /*----------------------------------------------------------------------*/
  340.  
  341. PROC varwin() OF varwin
  342.   DEF x:PTR TO scrolltext
  343.   self.next:=dwins
  344.   dwins:=self
  345.   self.type:=T_VAR
  346.   IF varlist=NIL THEN IF (varlist:=List(MAX_WATCH))=NIL THEN Raise("MEM")
  347.   constructvars()
  348.   self.scwin:=NEW x.settext(varlist,MAX_WLINE)
  349.   IF (fx>=xsize) OR (fy>=ysize) OR (fxs>=xsize) OR (fys>=ysize) OR (fxs<40) OR (fys<20)
  350.     fx:=xsize/8
  351.     fy:=ysize/2
  352.     fxs:=xsize-(xsize/4)
  353.     fys:=ysize/4
  354.   ENDIF
  355.   x.open('Variable View',fx,fy,fxs,fys,scr,IDCMP_MENUPICK OR IDCMP_MOUSEBUTTONS OR IDCMP_RAWKEY,{handlevar})
  356.   IF SetMenuStrip(x.window,menu)=FALSE THEN Raise("MENU")
  357.   vwin:=self
  358.   fx:=fy:=fxs:=fys:=0
  359. ENDPROC
  360.  
  361. PROC message() OF varwin
  362.   IF self.next THEN self.next.message()
  363.   IF self.scwin.handle() THEN END self
  364. ENDPROC
  365.  
  366. PROC refresh() OF varwin
  367.   varrefresh(self)
  368.   IF self.next THEN self.next.refresh()
  369. ENDPROC
  370.  
  371. PROC varrefresh(win:PTR TO varwin)
  372.   constructvars()
  373.   win.scwin.settext(varlist,MAX_WLINE)
  374.   win.scwin.refreshwindow()
  375. ENDPROC
  376.  
  377. PROC end() OF varwin
  378.   DEF sc:PTR TO scrolltext
  379.   vwin:=NIL
  380.   sc:=self.scwin
  381.   IF sc.window THEN ClearMenuStrip(sc.window)
  382.   END sc
  383.   SUPER self.end()
  384. ENDPROC
  385.  
  386. PROC actionvar(y)
  387.   DEF wv:PTR TO wvar,n=0,s[100]:STRING,v,vptr,type,r
  388.   wv:=vars.head
  389.   WHILE wv.succ
  390.     v,vptr,type:=getvarval(wv.v)
  391.     IF type
  392.       IF y=n++
  393.         StringF(s,'Variable "\s" selected.',wv.v)
  394.         r:=request3(s,'_Remove','_Modify','_Cancel',"r","m","c")
  395.         IF r=1
  396.           Remove(wv)
  397.           varrefresh(vwin)
  398.         ELSEIF r=2
  399.           StringF(s, IF (v>4096) OR (v<-4096) THEN '$\h' ELSE '\d', v)
  400.           r:=easyguiA(reqtitle,
  401.             [ROWS,
  402.               [TEXT,'New contents of variable?',NIL,FALSE,3],
  403.               [STR,1,'_Value:',s,100,10,0,0,"v"],
  404.               [COLS,[TEXT,'(Examples: 0,$0,var,{var})',NIL,FALSE,3],[BUTTON,{ehelp},'_Help',0,"h"]],
  405.               [BAR],
  406.               [COLS,
  407.                 [BUTTON,1,'_OK',0,"o"],
  408.                 [SPACEH],
  409.                 [BUTTON,0,'_Cancel',0,"c"]
  410.               ]
  411.             ],
  412.             [EG_SCRN,scr,NIL])
  413.           IF r=1
  414.             r,v:=extval(s)
  415.             IF r
  416.               SELECT 8 OF type
  417.                 CASE 3 TO 7
  418.                   frame.regs[type]:=v
  419.                 CASE 1,2
  420.                   ^vptr:=v
  421.               ENDSELECT
  422.               varrefresh(vwin)
  423.             ENDIF
  424.           ENDIF
  425.         ENDIF
  426.         RETURN
  427.       ENDIF
  428.     ENDIF
  429.     wv:=wv.succ
  430.   ENDWHILE
  431. ENDPROC
  432.  
  433. PROC addvar(var,shift=FALSE)
  434.   DEF wv:PTR TO wvar
  435.   IF openvarwin()
  436.     IF shift THEN getvarval(var,TRUE)
  437.     IF findtracedvar(var)
  438.       request1('You''re already watching this variable','_Indeed!',"i")
  439.     ELSE
  440.       AddTail(vars,NEW wv)
  441.       wv.v:=StrCopy(String(EstrLen(var)),var)
  442.       wv.name:=String(MAX_WLINE)
  443.       IF wv.name=NIL THEN Raise("MEM")
  444.       varrefresh(vwin)
  445.     ENDIF
  446.   ENDIF
  447. ENDPROC
  448.  
  449. PROC addval(s,v)
  450.   DEF vl:PTR TO LONG,a,c,t[20]:STRING
  451.   IF TypeOfMem(v)
  452.     vl:=v
  453.     StrAdd(s,' [')
  454.     FOR a:=1 TO 4 DO StrAdd(s,StringF(t,'\z\h[8] ',vl[]++))
  455.     StrAdd(s,' \q')
  456.     FOR a:=1 TO 16 DO (c:=v[]++) BUT StrAdd(s,IF (c>32) AND (c<127) THEN [c,0]:CHAR ELSE '.')
  457.     StrAdd(s,'\q]')
  458.   ENDIF
  459. ENDPROC
  460.  
  461. PROC findtracedvar(n)
  462.   DEF wv:PTR TO wvar
  463.   wv:=vars.head
  464.   WHILE wv.succ
  465.     IF StrCmp(n,wv.v) THEN RETURN wv
  466.     wv:=wv.succ
  467.   ENDWHILE
  468. ENDPROC NIL
  469.  
  470. PROC constructvars()
  471.   DEF wv:PTR TO wvar,num=0,v,vptr,type,t[30]:STRING
  472.   wv:=vars.head
  473.   WHILE wv.succ
  474.     v,vptr,type:=getvarval(wv.v)
  475.     IF type
  476.       StrCopy(wv.name,wv.v)
  477.       StrAdd(wv.name,StringF(t,IF (v>-1000) AND (v<1000) THEN ' = \d  ' ELSE ' = $\h  ',v))
  478.       SELECT 8 OF type
  479.         CASE 3 TO 7
  480.           StrAdd(wv.name,StringF(t,'(local reg D\d)',type))
  481.         CASE 1,2
  482.           StrAdd(wv.name,StringF(t,'(\s at $\z\h[8])',IF type=2 THEN 'global' ELSE 'local',vptr))
  483.       ENDSELECT
  484.       addval(wv.name,v)
  485.       varlist[num++]:=wv.name
  486.     ENDIF
  487.   EXIT num=MAX_WATCH
  488.     wv:=wv.succ
  489.   ENDWHILE
  490.   SetList(varlist,num)
  491. ENDPROC
  492.  
  493. /*-------------------------------------------------------------------*/
  494.  
  495. PROC showsrcwin(src:PTR TO e_source,i=NIL)
  496.   DEF w:PTR TO srcwin,n:PTR TO srcwin,sc:PTR TO scrolltext
  497.   w:=dwins
  498.   WHILE IF w THEN (IF w.type=T_SRC THEN w.src<>src ELSE w) ELSE w DO w:=w.next
  499.   IF w=NIL
  500.     NEW n.srcwin(src)
  501.   ELSE
  502.     n:=w
  503.     IF fxs
  504.       ChangeWindowBox(n.scwin.window,fx,fy,fxs,fys)
  505.       fx:=fy:=fxs:=fys:=0
  506.     ENDIF
  507.   ENDIF
  508.   sc:=n.scwin
  509.   IF i
  510.     sc.active(i)
  511.     activewin:=n
  512.   ENDIF
  513.   IF w THEN WindowToFront(sc.window)
  514. ENDPROC
  515.  
  516. PROC quit()
  517.   DEF a
  518.   a:=request3('Sure to leave the debugged program halfway?','_Quit','_Run','_Oops!',"q","r","o")
  519.   IF a=1
  520.     Raise()
  521.   ELSEIF a=2
  522.     whatstep:=STEP_RUN
  523.   ENDIF
  524. ENDPROC
  525.  
  526. PROC newmem()
  527.   DEF w:PTR TO memwin,a
  528.   IF (a:=getmem())<>-1 THEN NEW w.memwin(a,T_MEM)
  529. ENDPROC
  530.  
  531. PROC newreg() IS IF rwin THEN WindowToFront(rwin.scwin.window) ELSE NEW rwin.regwin()
  532. PROC openstackwin() IS IF stackwin=NIL THEN NEW stackwin.memwin(frame.stack,T_STACK) ELSE WindowToFront(stackwin.scwin.window)
  533. PROC openvarwin() IS IF vwin THEN (WindowToFront(vwin.scwin.window) BUT TRUE) ELSE NEW vwin.varwin()
  534. PROC dum(p,q) IS EMPTY
  535. PROC modifyvar() IS request13('You can modify a variable','by clicking on it','in the variable view','_Great!',"g")
  536. PROC watchvar() IS request13('You can watch a variable','by double-clicking on it','in a source-window','_Great!',"g")
  537. PROC breakpoint() IS request13('You can set a breakpoint','by double-clicking on a line','in a source-window','_Great!',"g")
  538.  
  539. PROC breakpointvar()
  540.   DEF m
  541.   IF (m:=getmem())<>-1 THEN setmembreak(m)
  542. ENDPROC
  543.  
  544. PROC clearbreakpoints()
  545.   setbreak(NIL)
  546.   setmembreak(NIL)
  547. ENDPROC
  548.  
  549. PROC raiseexception()
  550.   DEF e[20]:STRING,ei[20]:STRING,ev,eiv,n
  551.   StrCopy(e,'"HALT"')
  552.   StrCopy(ei,'0')
  553.   LOOP
  554.     IF easyguiA(reqtitle,
  555.       [EQROWS,
  556.         [TEXT,'Enter exception values:',NIL,FALSE,3],
  557.         [STR,{dum},'_exception:',e,100,5,0,0,"e"],
  558.         [STR,{dum},'e_xceptioninfo:',ei,100,5,0,0,"x"],
  559.         [COLS,[TEXT,'(Examples: 0,$0,var,{var})',NIL,FALSE,3],[BUTTON,{ehelp},'_Help',0,"h"]],
  560.         [BAR],
  561.         [COLS,
  562.           [BUTTON,1,'_OK',0,"o"],
  563.           [SPACEH],
  564.           [BUTTON,0,'_Cancel',0,"c"]
  565.         ]
  566.       ],
  567.       [EG_SCRN,scr,NIL])
  568.       n,ev:=extval(e)
  569.       IF n
  570.         n,eiv:=extval(ei)
  571.         IF n
  572.           setthrow(ev,eiv)
  573.           whatstep:=STEP_THROW
  574.           RETURN
  575.         ENDIF
  576.       ENDIF
  577.       request1('Illegal value(s)','_Sorry',"s")
  578.     ELSE
  579.       RETURN
  580.     ENDIF
  581.   ENDLOOP
  582. ENDPROC
  583.  
  584. PROC repeatstep()
  585.   DEF str[20]:STRING,n
  586.   StrCopy(str,'1')
  587.   LOOP
  588.     IF easyguiA(reqtitle,
  589.       [EQROWS,
  590.         [TEXT,'Enter number and type of steps:',NIL,FALSE,3],
  591.         [COLS,
  592.           [STR,{dum},'_Steps:',str,100,5,0,0,"s"],
  593.           [CHECK,{mrepeattype},'Step _Over?',repeatover,TRUE,0,"o"]
  594.         ],
  595.         [COLS,[TEXT,'(Examples: 10,$2F,var,^var)',NIL,FALSE,3],[BUTTON,{ehelp},'_Help',0,"h"]],
  596.         [BAR],
  597.         [COLS,
  598.           [BUTTON,1,'_OK',0,"o"],
  599.           [SPACEH],
  600.           [BUTTON,0,'_Cancel',0,"c"]
  601.         ]
  602.       ],
  603.       [EG_SCRN,scr,NIL])
  604.       n,repeatcount:=extval(str)
  605.       IF n AND (repeatcount>0)
  606.         repeatcount--
  607.         whatstep:=STEP_OVER
  608.         RETURN
  609.       ENDIF
  610.       request1('Illegal value(s)','_Sorry',"s")
  611.     ELSE
  612.       RETURN
  613.     ENDIF
  614.   ENDLOOP
  615. ENDPROC
  616.  
  617. PROC mrepeattype(p,x) IS repeatover:=x
  618.  
  619. PROC evalexps()
  620.   DEF r,s[100]:STRING
  621.   easyguiA(reqtitle,
  622.     [EQROWS,
  623.       [TEXT,'Enter E Expression:',NIL,FALSE,3],
  624.       [STR,{evexp},'_Exp:',s,100,10,0,0,"e"],
  625.       r:=[TEXT,s,'Result:',TRUE,1],
  626.       [COLS,[TEXT,'(Examples: 0,$0,var,{var})',NIL,FALSE,3],[BUTTON,{ehelp},'_Help',0,"h"]],
  627.       [BAR],
  628.       [COLS,[SPACEH],[BUTTON,0,'_OK',0,"o"],[SPACEH]]
  629.     ],
  630.     [EG_INFO,r, EG_SCRN,scr, EG_GHVAR,{evgh}, NIL])
  631. ENDPROC
  632.  
  633. PROC evexp(rgad,s)
  634.   DEF v,r,f[20]:STRING
  635.   r,v:=extval(s)
  636.   IF r
  637.     StringF(f,IF v<10000 THEN '\d' ELSE '$\h',v)
  638.   ELSE
  639.     StrCopy(f,'')
  640.   ENDIF
  641.   settext(evgh,rgad,f)
  642. ENDPROC
  643.  
  644. PROC ehelp(p)
  645.   easyguiA(reqtitle,
  646.     [ROWS,
  647.       [TEXT,'Values: 123, $ABC, %010101, "FORM"',NIL,FALSE,3],
  648.       [TEXT,'Variables: a, {a}, ^a',NIL,FALSE,3],
  649.       [TEXT,'Operators: +, -, *, /, ()',NIL,FALSE,3],
  650.       [BAR],
  651.       [BUTTON,0,'_OK',0,"o"]
  652.     ],
  653.     [EG_SCRN,scr,NIL])
  654. ENDPROC
  655.  
  656. PROC search()
  657.   DEF lines:PTR TO LONG,n,max,st:PTR TO scrolltext
  658.   max:=n:=ListLen(lines:=currentwin.src.lines())
  659.   st:=currentwin.scwin
  660.   IF easyguiA(reqtitle,
  661.       [ROWS,
  662.         [TEXT,'Enter text to find (case sensitive)',NIL,FALSE,3],
  663.         [STR,1,'_Text:',findstr,100,10,0,0,"t"],
  664.         [BAR],
  665.         [COLS,
  666.           [BUTTON,1,'_Find',0,"f"],
  667.           [SPACEH],
  668.           [BUTTON,0,'_Cancel',0,"c"]
  669.         ]
  670.       ],
  671.       [EG_SCRN,scr,NIL])
  672.     WHILE n>0
  673.       EXIT InStr(lines[],findstr,0)<>-1
  674.       lines++
  675.       n--
  676.     ENDWHILE
  677. ->    IF n THEN st.settop(max-n) ELSE request1('Could not find text','_Hmmm',"h")
  678.     IF n THEN st.active(max-n) ELSE request1('Could not find text','_Hmmm',"h")
  679.   ENDIF
  680. ENDPROC
  681.  
  682. PROC handlemenu(imsg:PTR TO intuimessage)
  683.   DEF c,menu,item,sub
  684.   c:=imsg.code
  685.   menu:=menunum(c)
  686.   item:=itemnum(c)
  687.   sub:=subnum(c)
  688.   SELECT menu
  689.     CASE 0
  690.       SELECT item
  691.         CASE 0; about()             -> About
  692.         CASE 1; setprefs()          -> Settings...
  693.         CASE 2; saveprefs()         -> Save Settings
  694.         CASE 3; quit()              -> Quit
  695.       ENDSELECT
  696.     CASE 1
  697.       SELECT item
  698.         CASE 0; choose_source()     -> Source
  699.         CASE 1; newreg()            -> Registers
  700.         CASE 2; newmem()            -> Memory
  701.         CASE 3; openstackwin()      -> Stack
  702.         CASE 4; openvarwin()        -> Variables
  703.       ENDSELECT
  704.     CASE 2
  705.       SELECT item
  706.         CASE 0; whatstep:=STEP_IN   -> Step In
  707.         CASE 1; whatstep:=STEP_OVER -> Step Over
  708.         CASE 2; whatstep:=STEP_FOLLOW -> Step Follow
  709.         CASE 3; repeatstep()        -> Repeat Step
  710.         CASE 4; watchvar()          -> Watch Variable
  711.         CASE 5; breakpoint()        -> Set Breakpoint on Sourceline
  712.         CASE 6; breakpointvar()     -> Set Breakpoint on Memory
  713.         CASE 7; clearbreakpoints()  -> Clear all Breakpoints
  714.         CASE 8; whatstep:=STEP_RUN  -> Run to Breakpoint
  715.         CASE 9; raiseexception()    -> Raise Exception
  716.       ENDSELECT
  717.     CASE 3
  718.       SELECT item
  719.         CASE 0; evalexps()          -> Eval E Expressions
  720.         CASE 1; modifyvar()         -> Modify Variable
  721.         CASE 2; dwins.refresh()     -> Refresh
  722.         CASE 3; search()            -> Find in Source
  723.         CASE 4; offset()            -> Locate Offset
  724.       ENDSELECT
  725.     CASE 4
  726.       SELECT item
  727.         CASE 0; exe_arexx_cmd(rxs1)
  728.         CASE 1; exe_arexx_cmd(rxs2)
  729.         CASE 2;    exe_arexx_cmd(rxs3)
  730.       ENDSELECT
  731.   ENDSELECT
  732. ENDPROC
  733.  
  734. PROC offset()
  735.   DEF v,r,i
  736.   IF easyguiA(reqtitle,
  737.       [ROWS,
  738.         [TEXT,'Enter offset to locate',NIL,FALSE,3],
  739.         [STR,1,'_Offset:',offstr,12,10,0,0,"o"],
  740.         [BAR],
  741.         [COLS,
  742.           [BUTTON,1,'_Locate',0,"l"],
  743.           [SPACEH],
  744.           [BUTTON,0,'_Cancel',0,"c"]
  745.         ]
  746.       ],
  747.       [EG_SCRN,scr,NIL])
  748.     v,r:=Val(offstr)
  749.     IF r
  750.       v,r,i:=exe.findoffset(v)
  751.       IF v
  752.         showsrcwin(v,r)
  753.         IF i THEN Delay(6) BUT request13('This might actually be an',
  754.                                          'E internal function, such',
  755.                                          'as Char() or WriteF()','_Oh',"o")
  756.       ELSE
  757.         request1('No line for this offset','_Oh',"o")
  758.       ENDIF
  759.     ELSE
  760.       request1('Bad offset','_Oh',"o")
  761.     ENDIF
  762.   ENDIF
  763. ENDPROC
  764.  
  765. PROC handlekey(c)
  766.   IF c=77 THEN whatstep:=STEP_OVER ELSE IF c=78 THEN whatstep:=STEP_IN
  767. ENDPROC
  768.  
  769. PROC handlesrc(data,imsg:PTR TO intuimessage)
  770.   DEF cl,vx,vy
  771.   IF data THEN currentwin:=data
  772.   IF (cl:=imsg.class)=IDCMP_MENUPICK
  773.     handlemenu(imsg)
  774.   ELSEIF cl=IDCMP_RAWKEY
  775.     handlekey(imsg.code)
  776.   ELSEIF cl=IDCMP_MOUSEBUTTONS
  777.     IF imsg.code=SELECTUP
  778.       IF DoubleClick(lastsec,lastmic,imsg.seconds,imsg.micros)
  779.         vx,vy:=currentwin.scwin.where(imsg.mousex,imsg.mousey)
  780.         IF vx<>-1 THEN dovar(vx,vy,imsg.qualifier)
  781.       ELSE
  782.         lastsec:=imsg.seconds
  783.         lastmic:=imsg.micros
  784.       ENDIF
  785.     ENDIF
  786.   ENDIF  
  787. ENDPROC
  788.  
  789. PROC handlevar(imsg:PTR TO intuimessage)
  790.   DEF cl,vx,vy
  791.   IF (cl:=imsg.class)=IDCMP_MENUPICK
  792.     handlemenu(imsg)
  793.   ELSEIF cl=IDCMP_RAWKEY
  794.     handlekey(imsg.code)
  795.   ELSEIF cl=IDCMP_MOUSEBUTTONS
  796.     IF vwin
  797.       vx,vy:=vwin.scwin.where(imsg.mousex,imsg.mousey)
  798.       IF imsg.code=SELECTDOWN
  799.         oldvy:=vy
  800.       ELSEIF imsg.code=SELECTUP
  801.         IF (vx<>-1) AND (oldvy=vy) THEN actionvar(vy)
  802.         oldvy:=-1
  803.       ENDIF
  804.     ENDIF
  805.   ENDIF  
  806. ENDPROC
  807.  
  808. PROC getvarval(var,send=FALSE)
  809.   DEF isglob,v,vptr,x,type=0,mess[256]:STRING,evar:PTR TO e_var
  810.   IF (x:=activewin.scwin.getactive())<>-1
  811.     evar,isglob:=activewin.src.findvar(var,activewin.src.findproc(x))
  812.     IF evar
  813.       IF type:=evar.regno
  814.         v:=frame.regs[type]
  815.         vptr:=0
  816.       ELSEIF evar.offs
  817.         v:=Long(vptr:=frame.regs[IF isglob THEN 12 ELSE 13]+evar.offs)
  818.         type:=IF isglob THEN 2 ELSE 1
  819.       ENDIF
  820.       IF send
  821.         x:=evar.type
  822.         StringF(mess,'[\s] \s',IF isglob THEN 'Global' ELSE 'Local', var)
  823.         IF x
  824.           StrAdd(mess,':PTR TO ')
  825.           StrAdd(mess,x)
  826.         ENDIF
  827.         SelectOutput(NIL)
  828.         IF sendExplorer(v,x,NIL,mess,TRUE)=FALSE
  829.           IF runExplorer()=0
  830.             FOR send:=1 TO 20
  831.               Delay(6)
  832.             EXIT isExplorerRunning()
  833.             ENDFOR
  834.             IF send<=20
  835.               sendExplorer(v,x,NIL,mess,TRUE)
  836.               startExp:=TRUE
  837.             ENDIF
  838.           ENDIF
  839.         ENDIF
  840.         SelectOutput(ocon)
  841.       ENDIF
  842.     ENDIF
  843.   ENDIF
  844. ENDPROC v,vptr,type
  845.  
  846. PROC runExplorer()
  847.   DEF cmd[256]:STRING
  848.   StrCopy(cmd,IF explorer[] THEN explorer ELSE 'explorer')
  849.   IF pubname[]
  850.     StrAdd(cmd,' SCREEN="')
  851.     StrAdd(cmd,pubname)
  852.     StrAdd(cmd,'"')
  853.   ENDIF
  854. ENDPROC SystemTagList(cmd,[SYS_ASYNCH,TRUE, SYS_INPUT,NIL, SYS_OUTPUT,NIL, NIL])
  855.  
  856. PROC dovar(vx,vy,qual)
  857.   DEF var[50]:STRING,v,vptr,reg=0
  858.   vy:=currentwin.src.locate(vx,vy,var)
  859.   IF var[] THEN v,vptr,reg:=getvarval(var)
  860.   IF reg
  861.     addvar(var,qual AND 3)
  862.   ELSEIF vy>=0
  863.     v:=request3('Put breakpoint here?','_OK','OK and _Run','_Cancel',"o","r","c")
  864.     IF v>0
  865.       setbreak(currentwin.src.findpc(vy,exe))
  866.       IF v>1 THEN whatstep:=STEP_RUN
  867.     ENDIF
  868.   ENDIF
  869. ENDPROC
  870.  
  871. PROC makefollow()
  872.   IF followgh=NIL
  873.     followgh:=guiinitA('** EDBG ** Following Execution ** Close Me to Stop! **',
  874.           [SPACEH],
  875.           [EG_LEFT,0, EG_TOP,0, EG_MAXW,TRUE, EG_SCRN,scr,
  876.            EG_WTYPE,WTYPE_NOSIZE, NIL])
  877.   ENDIF
  878. ENDPROC
  879.  
  880. PROC removefollow()
  881.   IF followgh
  882.     cleangui(followgh)
  883.     followgh:=NIL
  884.   ENDIF
  885. ENDPROC
  886.  
  887. PROC step(fr:PTR TO stackframe)
  888.   DEF pc,src,i
  889.   IF repeatcount
  890.     repeatcount--
  891.     IF repeatover
  892.       stepover(fr,fr.regs[13])
  893.     ELSE
  894.       stepover()
  895.     ENDIF
  896.   ELSE
  897.     frame:=fr
  898.     IF stackwin THEN stackwin.addr:=fr.stack
  899.     pc:=fr.returnpc-2
  900.     src,i,pc:=exe.findline(pc)
  901.     IF src=NIL
  902.       removefollow()
  903.       request13('Your program caused a guru!',
  904.                 'It may not be safe to continue running this program,',
  905.                 'you might even need to reboot!',
  906.                 '_Oops!',"o")
  907.       -> Try it now with last known PC
  908.       src,i:=exe.findline(pc)
  909.     ENDIF
  910.     IF src THEN showsrcwin(src,i)
  911.     whatstep:=STEP_NONE
  912.     IF dorefresh THEN dwins.refresh()
  913.     IF followgh
  914.       WindowToFront(followgh.wnd)
  915.       ActivateWindow(followgh.wnd)
  916.       Delay(followspeed)
  917.       IF guimessage(followgh)<0
  918.         stepover()
  919.       ELSE
  920.         removefollow()
  921.       ENDIF
  922.     ENDIF
  923.     IF followgh=NIL
  924.       IF first_step_done=FALSE
  925.         unreachablea7:=fr+100000            -> imp! beyond main stack level
  926.         first_step_done:=TRUE
  927.         exe_arexx_cmd('.edbg-startup.rexx')
  928.         IF doabout THEN Delay(6) BUT about()
  929.       ENDIF
  930.       REPEAT
  931.         Wait(-1)
  932.         srcmessage()
  933.         IF dwins THEN dwins.message()
  934.         rexxmessage()
  935.         toolmessage()
  936.       UNTIL whatstep
  937.       SELECT whatstep
  938.         CASE STEP_IN;    stepover()
  939.         CASE STEP_OVER;  stepover(fr,fr.regs[13])
  940.         CASE STEP_RUN;   stepover(unreachablea7,unreachablea7)
  941.         CASE STEP_THROW; stepover(); RETURN TRUE
  942.         CASE STEP_FOLLOW
  943.           makefollow()
  944.           stepover()
  945.       ENDSELECT
  946.     ENDIF
  947.   ENDIF
  948. ENDPROC FALSE
  949.  
  950. PROC srcmessage()
  951.   DEF s:PTR TO scrollwin, srcwin:PTR TO srcwin
  952.   WHILE s:=handleIDCMP(srcport)
  953.     srcwin:=s.data
  954.     END srcwin
  955.   ENDWHILE
  956. ENDPROC
  957.  
  958. /*--------------------------------------------------------------------*/
  959.  
  960. CONST TOOL_NUM=6,TOOL_ONEH=32,TOOL_W=37,TOOL_SP=2
  961. CONST TOOL_HEIGHT=TOOL_ONEH+TOOL_SP*TOOL_NUM-TOOL_SP
  962. CONST TOOL_SIZE=TOOL_HEIGHT*12
  963.  
  964. PROC toolmessage()
  965.   DEF imsg:PTR TO intuimessage,cl
  966.   WHILE imsg:=GetMsg(toolwin.userport)
  967.     cl:=imsg.class
  968.     SELECT cl
  969.       CASE IDCMP_MENUPICK
  970.         handlemenu(imsg)
  971.       CASE IDCMP_GADGETUP
  972.         SELECT 7 OF imsg.iaddress::gadget.gadgetid
  973.           CASE 1; whatstep:=STEP_OVER
  974.           CASE 2; whatstep:=STEP_IN
  975.           CASE 3; newmem()
  976.           CASE 4; newreg()
  977.           CASE 5; openvarwin()
  978.           CASE 6; quit()
  979.         ENDSELECT
  980.     ENDSELECT
  981.     ReplyMsg(imsg)
  982.   ENDWHILE
  983. ENDPROC
  984.  
  985. PROC createtoolbar()
  986.   DEF m,i,a,b=1,gads=NIL:PTR TO gadget,aw,ah,al,at,ab,ar,wpos
  987.   wpos:=font.ysize+scr.wbortop+1
  988.   al:=scr.wborleft+2
  989.   at:=wpos+2
  990.   ab:=scr.wborbottom+2
  991.   ar:=scr.wborright+2
  992.   aw:=al+ar+TOOL_W
  993.   ah:=at+ab+TOOL_HEIGHT
  994.   IF (toolgads:=List(TOOL_NUM))=NIL THEN Raise("MEM")
  995.   SetList(toolgads,TOOL_NUM)
  996.   CopyMem({tooldata},m:=NewM(TOOL_SIZE,2),TOOL_SIZE)
  997.   i:=[0,0,TOOL_W,TOOL_HEIGHT,2,m,%11,0,NIL]:image
  998.   MapList({a},toolgads,toolgads,
  999.       `gads:=NEW [gads,al,b-1*(TOOL_ONEH+TOOL_SP)+at,TOOL_W,TOOL_ONEH,
  1000.                   GFLG_GADGHCOMP,GACT_RELVERIFY,GTYP_BOOLGADGET,
  1001.                   NIL,NIL,NIL,0,NIL,b++,0]:gadget)
  1002.   IF ForAll({a},toolgads,`a)=FALSE THEN Raise("MEM")
  1003.   IF (toolwin:=OpenW(0,wpos,aw,Min(ah,ysize-wpos),
  1004.     IDCMP_GADGETUP OR IDCMP_MENUPICK,
  1005.     6 OR WFLG_NEWLOOKMENUS,'          Toolbar',scr,15,gads))=NIL THEN Raise("WIN")
  1006.   DrawImage(toolwin.rport,i,al,at)
  1007.   IF SetMenuStrip(toolwin,menu)=FALSE THEN Raise("MENU")
  1008.   RefreshWindowFrame(toolwin)
  1009.   Dispose(m)
  1010. ENDPROC
  1011.  
  1012. PROC deletetoolbar()
  1013.   IF toolwin THEN ClearMenuStrip(toolwin)
  1014.   CloseW(toolwin)
  1015.   toolwin:=NIL
  1016. ENDPROC
  1017.  
  1018. tooldata: INCBIN 'pix/toolbar.raw'
  1019.  
  1020. /*-----------------------------------------------------------------*/
  1021.  
  1022. aboutdata: INCBIN 'pix/about.raw'
  1023.  
  1024. CONST ABOUT_SIZE=7872,ABOUT_HEIGHT=164,ABOUT_WIDTH=182
  1025.  
  1026. PROC about()
  1027.   DEF m,i,win=NIL:PTR TO window,aw,ah,al,at,ab,ar
  1028.   al:=scr.wborleft+2
  1029.   at:=font.ysize+scr.wbortop+1+2
  1030.   ab:=scr.wborbottom+2
  1031.   ar:=scr.wborright+2
  1032.   aw:=al+ar+ABOUT_WIDTH
  1033.   ah:=at+ab+ABOUT_HEIGHT
  1034.   CopyMem({aboutdata},m:=NewM(ABOUT_SIZE,2),ABOUT_SIZE)
  1035.   i:=[0,0,ABOUT_WIDTH,ABOUT_HEIGHT,2,m,%11,0,NIL]:image
  1036.   IF win:=OpenW(xsize-ABOUT_WIDTH/2,ysize-ABOUT_HEIGHT/2,aw,ah,
  1037.       IDCMP_CLOSEWINDOW OR IDCMP_RAWKEY OR IDCMP_MOUSEBUTTONS,$100E,'About...',scr,15,NIL)
  1038.     DrawImage(win.rport,i,al,at)
  1039.     WaitIMessage(win)
  1040.     CloseW(win)
  1041.   ENDIF
  1042.   Dispose(m)
  1043. ENDPROC
  1044.  
  1045. /*-----------------------------------------------------------------*/
  1046.  
  1047. PROC request1(body,gadget,key) IS easyguiA(reqtitle,[ROWS,[TEXT,body,NIL,FALSE,3],[BAR],[BUTTON,0,gadget,0,key]],[EG_SCRN,scr,NIL])
  1048. PROC request13(b1,b2,b3,gadget,key) IS easyguiA(reqtitle,[ROWS,[TEXT,b1,NIL,FALSE,3],[TEXT,b2,NIL,FALSE,3],[TEXT,b3,NIL,FALSE,3],[BAR],[BUTTON,0,gadget,0,key]],[EG_SCRN,scr,NIL])
  1049. PROC request3(body,g1,g2,g3,k1,k2,k3) IS easyguiA(reqtitle,[ROWS,[TEXT,body,NIL,FALSE,3],[BAR],[COLS,[BUTTON,1,g1,0,k1],[SPACEH],[BUTTON,2,g2,0,k2],[SPACEH],[BUTTON,0,g3,0,k3]]],[EG_SCRN,scr,NIL])
  1050.  
  1051. PROC getmem()
  1052.   DEF ok,s[100]:STRING,r,v,p
  1053.   REPEAT
  1054.     ok:=1
  1055.     r:=easyguiA(reqtitle,
  1056.       [ROWS,
  1057.         [TEXT,'Which memory location?',NIL,FALSE,3],
  1058.         [STR,1,'_Addr:',s,100,10,0,0,"a"],
  1059.         [COLS,[TEXT,'(Examples: 0,$0,var,{var})',NIL,FALSE,3],[BUTTON,{ehelp},'_Help',0,"h"]],
  1060.         [BAR],
  1061.         [COLS,
  1062.           [BUTTON,1,'_OK',0,"o"],
  1063.           [SPACEH],
  1064.           [BUTTON,0,'_Cancel',0,"c"]
  1065.         ]
  1066.       ],
  1067.       [EG_SCRN,scr,NIL])
  1068.     IF r
  1069.       r,v:=extval(s)
  1070.       IF r
  1071.         IF TypeOfMem(v)=FALSE
  1072.           ok:=request3('Not a valid ram-address','_Do it anyway','_Oops','_Cancel',"d","o","c")
  1073.         ENDIF
  1074.       ELSE
  1075.         ok:=2
  1076.       ENDIF
  1077.     ELSE
  1078.       ok:=0
  1079.     ENDIF
  1080.   UNTIL ok<2
  1081. ENDPROC IF ok THEN v AND -2 ELSE -1
  1082.  
  1083. PROC extval(s)
  1084.   DEF v
  1085.   s,v:=exp(s)
  1086.   IF s=0 THEN request1('Syntax Error in Expression','_Um',"u")
  1087. ENDPROC s,v
  1088.  
  1089. PROC exp(s)
  1090.   DEF v=0,o,v2
  1091.   s,v:=factor(s)
  1092.   IF s
  1093.     s:=whitesp(s)
  1094.     WHILE o:=s[]++
  1095.       IF o=")" THEN RETURN s-1,v
  1096.       s,v2:=factor(s)
  1097.       IF s=0 THEN RETURN 0
  1098.       SELECT o
  1099.         CASE "+"; v:=v+v2
  1100.         CASE "-"; v:=v-v2
  1101.         CASE "*"; v:=Mul(v,v2)
  1102.         CASE "/"; v:=Div(v,v2)
  1103.         DEFAULT; RETURN request1('Missing operator','_Oh',"o")
  1104.       ENDSELECT
  1105.       s:=whitesp(s)
  1106.     ENDWHILE
  1107.   ENDIF
  1108. ENDPROC s,v
  1109.  
  1110. PROC factor(s)
  1111.   DEF v,r,c,a,neg=FALSE
  1112.   v,r:=Val(s)
  1113.   IF r
  1114.     s:=s+r
  1115.   ELSE
  1116.     s:=whitesp(s)
  1117.     IF s[]="-"
  1118.       s:=whitesp(s+1)
  1119.       neg:=TRUE
  1120.     ENDIF
  1121.     IF s[]="\q"
  1122.       s++
  1123.       a:=v:=0
  1124.       WHILE (c:=s[]++)<>"\q"
  1125.         EXIT a++=4
  1126.         v:=Shl(v,8)+c
  1127.       ENDWHILE
  1128.       IF c<>"\q" THEN RETURN request1('Missing "','_Oh',"o")
  1129.     ELSEIF s[]="{"
  1130.       s++
  1131.       s:=whitesp(s)
  1132.       s,r,v:=id(s,TRUE)
  1133.       IF s
  1134.         s:=whitesp(s)
  1135.         IF s[]++<>"}" THEN RETURN request1('Missing "}"','_Oh',"o")
  1136.       ENDIF
  1137.     ELSEIF s[]="^"
  1138.       s++
  1139.       s:=whitesp(s)
  1140.       s,v:=id(s)
  1141.       v:=^v
  1142.     ELSEIF s[]="("
  1143.       s++
  1144.       s,v:=exp(s)
  1145.       IF s THEN IF s[]++<>")" THEN RETURN request1('Missing ")"','_Oh',"o")
  1146.     ELSE
  1147.       s,v:=id(s)
  1148.     ENDIF
  1149.   ENDIF
  1150. ENDPROC s,IF neg THEN -v ELSE v
  1151.  
  1152. PROC id(s,isaddr=FALSE)
  1153.   DEF r,v,t,str[50]:STRING,c
  1154.   WHILE (((c:=s[]++)>="a") AND (c<="z")) OR ((c>="A") AND (c<="Z")) OR (c="_") DO StrAdd(str,[c,0]:CHAR)
  1155.   s--
  1156.   IF str[]=0 THEN RETURN 0
  1157.   v,r,t:=getvarval(str)
  1158.   IF t=0 THEN RETURN request1('Unknown var','_Oops',"o")
  1159.   IF isaddr THEN IF t>=3 THEN RETURN request13('You can''t take the address','of a register variable.','Recompile without OPTI/S or REG/K','_Sure',"s")
  1160. ENDPROC s,v,r
  1161.  
  1162. PROC whitesp(s)
  1163.   WHILE s[]=" " DO s++
  1164. ENDPROC s
  1165.  
  1166. PROC setprefs()
  1167.   easyguiA('EDBG Preferences',
  1168.     [ROWS,
  1169.       [EQROWS,
  1170.         [CHECK,{mdoabout},'_Show "About..." on startup',doabout,TRUE,0,"s"],
  1171.         [CHECK,{mdorefresh},'_Refresh views each step',dorefresh,TRUE,0,"r"],
  1172.         [CHECK,{mdowins},'Save _current window positions',dosavewindowpos,TRUE,0,"c"],
  1173.         [CHECK,{mdovars},'Save _watched variable names',dosavevars,TRUE,0,"w"]
  1174.       ],
  1175.       [SLIDE,{mspeed},'Follow Delay (0.1sec):    ',FALSE,0,30,followspeed/5,2,'%3ld'],
  1176.       [BAR],
  1177.       [EQROWS,
  1178.         [STR,{dstr},'_Arexx script 1',rxs1,RXSTR_SIZE,4,0,0,"a"],
  1179.         [STR,{dstr},'Arexx script 2',rxs2,RXSTR_SIZE,4],
  1180.         [STR,{dstr},'Arexx script 3',rxs3,RXSTR_SIZE,4]
  1181.       ],
  1182.       [BAR],
  1183.       [STR,{dstr},'_Explorer',explorer,RXSTR_SIZE,4,0,0,"e"],
  1184.       [BAR],
  1185.       [BUTTON,0,'_OK',0,"o"]
  1186.     ],
  1187.     [EG_SCRN,scr,NIL])
  1188. ENDPROC
  1189.  
  1190. PROC mdoabout(p,x) IS doabout:=x
  1191. PROC mdorefresh(p,x) IS dorefresh:=x
  1192. PROC mdowins(p,x) IS dosavewindowpos:=x
  1193. PROC mdovars(p,x) IS dosavevars:=x
  1194. PROC dstr(p,q) IS EMPTY
  1195. PROC mspeed(p,x) IS followspeed:=x*5
  1196.  
  1197. PROC saveprefs()
  1198.   DEF fh,ofh,dw:PTR TO dbgwin,wv:PTR TO wvar,win:PTR TO window
  1199.   IF fh:=Open('.edbg-startup.rexx',NEWFILE)
  1200.     ofh:=SetStdOut(fh)
  1201.     WriteF('/* generated by EDBG */\n\n/* address EDBG */\n\n')
  1202.     IF doabout=FALSE THEN WriteF('''noabout''\n')
  1203.     IF dorefresh=FALSE THEN WriteF('''norefresh''\n')
  1204.     IF dosavewindowpos
  1205.       dw:=dwins
  1206.       WHILE dw
  1207.         IF dw.type=T_VAR
  1208.           win:=dw::varwin.scwin.window
  1209.           WriteF('''variables \d \d \d \d''\n',win.leftedge,win.topedge,win.width,win.height)
  1210.         ELSEIF dw.type=T_MEM
  1211.           WriteF('''memory \d''\n',dw::memwin.addr)
  1212.         ELSEIF dw.type=T_SRC
  1213.           win:=dw::srcwin.scwin.window
  1214.           WriteF('''srcwindow \s \d \d \d \d''\n',dw::srcwin.src.name(),win.leftedge,win.topedge,win.width,win.height)
  1215.         ENDIF
  1216.         dw:=dw.next
  1217.       ENDWHILE
  1218.     ENDIF
  1219.     IF dosavevars
  1220.       IF vars.tailpred<>vars
  1221.         WriteF('''watch')
  1222.         iterate_exec_list({wv},vars,`WriteF(' \s',wv.v))
  1223.         WriteF('''\n')
  1224.       ENDIF
  1225.     ENDIF
  1226.     IF explorer[] THEN WriteF('''explorer \s''\n',explorer)
  1227.     IF rxs1[] THEN WriteF('''rexx 1 \s''\n',rxs1)
  1228.     IF rxs2[] THEN WriteF('''rexx 2 \s''\n',rxs2)
  1229.     IF rxs3[] THEN WriteF('''rexx 3 \s''\n',rxs3)
  1230.     SetStdOut(ofh)
  1231.     Close(fh)
  1232.   ELSE
  1233.     request1('Unable to write prefs','_Hmmm...',"h")
  1234.   ENDIF
  1235. ENDPROC
  1236.  
  1237. PROC choose_source() HANDLE
  1238.   DEF l,s:PTR TO e_source,a=0,num=-1
  1239.   s:=exe.sources()
  1240.   l:=newlist()
  1241.   WHILE s
  1242.     AddTail(l,newnode(NIL,s.name()))
  1243.     s:=s.next()
  1244.   ENDWHILE
  1245.   easyguiA(reqtitle,
  1246.     [EQROWS,
  1247.        [LISTV,{sourcenum},'Select Source:',12,5,l,FALSE,0,0],
  1248.        [BAR],
  1249.        [COLS,[SPACEH],[BUTTON,0,'_Cancel',0,"c"],[SPACEH]]
  1250.     ],
  1251.     [EG_INFO,{num}, EG_SCRN,scr, NIL])
  1252. EXCEPT DO
  1253.   IF num>=0
  1254.     s:=exe.sources()
  1255.     WHILE s
  1256.       EXIT a++=num
  1257.       s:=s.next()
  1258.     ENDWHILE
  1259.     IF s THEN showsrcwin(s)
  1260.   ENDIF
  1261. ENDPROC
  1262.  
  1263. PROC sourcenum(i,n)
  1264.   ^i:=n
  1265.   Raise()
  1266. ENDPROC
  1267.  
  1268. PROC rexxmessage()
  1269.   DEF mes,rexxstr
  1270.   IF rexxport
  1271.     WHILE TRUE
  1272.       mes,rexxstr:=rx_GetMsg(rexxport)
  1273.     EXIT mes=NIL
  1274.       rexxcontinue(rexxstr,mes)
  1275.     ENDWHILE
  1276.   ENDIF
  1277. ENDPROC
  1278.  
  1279. PROC rexxcontinue(rexxstr,mes) HANDLE    -> called from other spots too
  1280.   DEF rc=0,rstr=NIL
  1281.   rc,rstr:=processcmd(rexxstr)
  1282. EXCEPT DO
  1283.   rx_ReplyMsg(mes,rc,rstr)
  1284.   ReThrow()
  1285. ENDPROC
  1286.  
  1287. PROC getword(s,dest)
  1288.   DEF b,c
  1289.   LOOP
  1290.     SELECT 256 OF c:=s[]++
  1291.       CASE 0; request1('Argument to Arexx command expected','_Oh',"o"); Raise()
  1292.       CASE " ", "\t"
  1293.       CASE 33 TO 255
  1294.         b:=s-1
  1295.         WHILE (s[]>" ") AND (s[]<=255) DO s++
  1296.         StrCopy(dest,b,s-b)
  1297.         WHILE (s[]=" ") OR (s[]="\t") DO s++
  1298.         RETURN s
  1299.       DEFAULT
  1300.         request1('Garbage in Arexx command','_Oh',"o"); Raise()
  1301.     ENDSELECT
  1302.   ENDLOOP
  1303. ENDPROC
  1304.  
  1305. PROC getexp(s)
  1306.   DEF v,dest[250]:STRING,sr
  1307.   s:=getword(s,dest)
  1308.   sr,v:=extval(dest)
  1309.   IF sr=NIL THEN Raise()
  1310. ENDPROC s,v
  1311.  
  1312. PROC processcmd(s)
  1313.   DEF rc=0,rstr=NIL,ts[250]:STRING,a,b,esrc=NIL:PTR TO e_source,w:PTR TO memwin,vptr,type
  1314.   s:=getword(s,ts)
  1315.   UpperStr(ts)
  1316.   IF StrCmp(ts,'QUIT')
  1317.     quit()
  1318.   ELSEIF StrCmp(ts,'RUN')
  1319.     whatstep:=STEP_RUN
  1320.   ELSEIF StrCmp(ts,'MEMORY')
  1321.     s,a:=getexp(s)
  1322.     NEW w.memwin(a,T_MEM)
  1323.   ELSEIF StrCmp(ts,'EXPLORER')
  1324.     s:=getword(s,explorer)
  1325.   ELSEIF StrCmp(ts,'REXX')
  1326.     s,a:=getexp(s)
  1327.     IF a=1
  1328.       s:=getword(s,rxs1)
  1329.     ELSEIF a=2
  1330.       s:=getword(s,rxs2)
  1331.     ELSEIF a=3
  1332.       s:=getword(s,rxs3)
  1333.     ENDIF
  1334.   ELSEIF StrCmp(ts,'VARIABLES')
  1335.     s,fx:=getexp(s)
  1336.     s,fy:=getexp(s)
  1337.     s,fxs:=getexp(s)
  1338.     s,fys:=getexp(s)
  1339.     openvarwin()
  1340.   ELSEIF StrCmp(ts,'STEPIN')
  1341.     whatstep:=STEP_IN
  1342.   ELSEIF StrCmp(ts,'STEPOVER')
  1343.     whatstep:=STEP_OVER
  1344.   ELSEIF StrCmp(ts,'WATCH')
  1345.     WHILE s[]
  1346.       s:=getword(s,ts)
  1347.       addvar(ts)
  1348.     ENDWHILE
  1349.   ELSEIF StrCmp(ts,'BREAKPOINT')
  1350.     s,a:=getexp(s)
  1351.     setbreak(currentwin.src.findpc(a,exe))
  1352.   ELSEIF StrCmp(ts,'EVAL')
  1353.     s,rc:=getexp(s)
  1354.   ELSEIF StrCmp(ts,'MEMORYBREAKPOINT')
  1355.     s,a:=getexp(s)
  1356.     setmembreak(a)
  1357.   ELSEIF StrCmp(ts,'RAISE')
  1358.     s,a:=getexp(s)
  1359.     s,b:=getexp(s)
  1360.     setthrow(a,b)
  1361.     whatstep:=STEP_THROW
  1362.   ELSEIF StrCmp(ts,'SRCWINDOW')
  1363.     s:=getword(s,ts)
  1364.     s,fx:=getexp(s)
  1365.     s,fy:=getexp(s)
  1366.     s,fxs:=getexp(s)
  1367.     s,fys:=getexp(s)
  1368.     IF esrc:=exe.sources() THEN esrc:=esrc.findsrc(ts)
  1369.     IF esrc THEN showsrcwin(esrc)
  1370.   ELSEIF StrCmp(ts,'NOABOUT')
  1371.     doabout:=FALSE
  1372.   ELSEIF StrCmp(ts,'NOREFRESH')
  1373.     dorefresh:=FALSE
  1374.   ELSEIF StrCmp(ts,'ASSIGN')
  1375.     s:=getword(s,ts)
  1376.     s,a:=getexp(s)
  1377.     b,vptr,type:=getvarval(ts)
  1378.     SELECT 8 OF type
  1379.       CASE 3 TO 7
  1380.         frame.regs[type]:=a
  1381.       CASE 1,2
  1382.         ^vptr:=a
  1383.     ENDSELECT
  1384.   ELSE
  1385.     request13('Unknown Arexx command:',ts,'received','_Really?',"r")
  1386.     s:=''
  1387.   ENDIF
  1388.   IF s[] THEN request13('Superfluous arguments:',ts,'in Arexx command','_Really?',"r")
  1389. ENDPROC rc,rstr
  1390.  
  1391. PROC exe_arexx_cmd(cmdstr) HANDLE    -> either a file name or a quoted string
  1392.   DEF rexx,rmsg=NIL:PTR TO rexxmsg,rarg=NIL,forb,noreply=TRUE,rrmsg:PTR TO rexxmsg,cstr
  1393.   rexxsysbase:=NIL
  1394.   Forbid(); forb:=TRUE
  1395.   IF (rexx:=FindPort('REXX'))=NIL THEN Raise()
  1396.   IF (rexxsysbase:=OpenLibrary('rexxsyslib.library',0))=NIL THEN Raise()
  1397.   IF (rmsg:=CreateRexxMsg(rexxport,'rexx',rexxname))=NIL THEN Raise()
  1398.   IF (rarg:=CreateArgstring(cmdstr,StrLen(cmdstr)))=NIL THEN Raise()
  1399.   rmsg.args[0]:=rarg
  1400.   rmsg.action:=RXCOMM
  1401.   PutMsg(rexx,rmsg)
  1402.   Permit(); forb:=FALSE
  1403.   WriteF('executing script \s\n',cmdstr)
  1404.   WHILE noreply
  1405.     Wait(-1)
  1406.     WHILE TRUE
  1407.       rrmsg,cstr:=rx_GetMsg(rexxport)
  1408.     EXIT rrmsg=NIL
  1409.       IF rrmsg::ln.type=NT_REPLYMSG
  1410.         WriteF('done with script \s\n',cmdstr)
  1411.         noreply:=FALSE
  1412.       ELSE
  1413.         rexxcontinue(cstr,rrmsg)
  1414.       ENDIF
  1415.     ENDWHILE
  1416.   ENDWHILE
  1417. EXCEPT DO
  1418.   IF forb THEN Permit()
  1419.   IF rarg THEN DeleteArgstring(rarg)
  1420.   IF rmsg THEN DeleteRexxMsg(rmsg)
  1421.   IF rexxsysbase THEN CloseLibrary(rexxsysbase)
  1422. ENDPROC
  1423.  
  1424. CHAR 0, '$VER: EDBG 3.3a', 0, 0
  1425.